
import ParserError from "@/js/GraphParser/src/ParserError"
import { GraphNode } from "@/js/components/GraphNode"
import { GraphView } from "@/js/components/GraphView"
import { InputLinkNodeAny, InputLinkNodeBoolean, InputLinkNodeColor, InputLinkNodeFlow, InputLinkNodeFunction, InputLinkNodeGroup, InputLinkNodeNumber, InputLinkNodeObject, InputLinkNodeString } from "@/js/components/InputLinkNode"

export class Class extends GraphNode{
    group?: InputLinkNodeGroup
    leftGroup?: InputLinkNodeGroup
    load(){
        super.load()

        const layout = new this.DefaultLayout(this, this.graphView as GraphView, true, true)
        this.layout = layout
        this.appendChild(layout.container)
        
        // 引用
        layout.main?.left.appendChild(new InputLinkNodeString(this, this.graphView as GraphView, {
            name: "funName", 
            desc: '类名称',
            model: 'entry',
            placeholder: "类名称",
            showLinkNode: false,
        }))

        // 引用
        layout.main?.right.appendChild(new InputLinkNodeFunction(this, this.graphView as GraphView, {
            name: "quote", 
            desc: '引用',
            model: "output",
            showInput: false,
            linkMaxCount: 100000
        }))

        const leftGroup = new InputLinkNodeGroup( this, this.graphView as GraphView , {
            name: 'attributes'
        }).addInputLinkNode("属性-字符串(string)", InputLinkNodeString, {
            name: '',
            desc: '字符串(string)',
            model: 'entry',
            inputTypeString: true,
            placeholder: '变量名称',
            inputValue: '',
            isBindValue: false
        }).addInputLinkNode("属性-数值(number)", InputLinkNodeNumber, {
            name: '',
            desc: '数值(number)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        }).addInputLinkNode("属性-布尔(boolean)", InputLinkNodeBoolean, {
            name: '',
            desc: '布尔(boolean)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        }).addInputLinkNode("属性-对象(object)", InputLinkNodeObject, {
            name: '',
            desc: '对象(object)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        }).addInputLinkNode("属性-函数(function)", InputLinkNodeFunction, {
            name: '',
            desc: '函数(function)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        }).addInputLinkNode("属性-通用(any)", InputLinkNodeAny, {
            name: '',
            desc: '通用(any)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        })
        .addInputLinkNode("静态属性-字符串(string)", InputLinkNodeString, {
            name: '',
            desc: '静态属性字符串(string)',
            model: 'entry',
            inputTypeString: true,
            placeholder: '变量名称',
            inputValue: '',
            isBindValue: false
        }).addInputLinkNode("静态属性-数值(number)", InputLinkNodeNumber, {
            name: '',
            desc: '静态属性数值(number)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        }).addInputLinkNode("静态属性-布尔(boolean)", InputLinkNodeBoolean, {
            name: '',
            desc: '静态属性布尔(boolean)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        }).addInputLinkNode("静态属性-对象(object)", InputLinkNodeObject, {
            name: '',
            desc: '静态属性对象(object)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        }).addInputLinkNode("静态属性-函数(function)", InputLinkNodeFunction, {
            name: '',
            desc: '静态属性函数(function)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        }).addInputLinkNode("静态属性-通用(any)", InputLinkNodeAny, {
            name: '',
            desc: '静态属性通用(any)',
            model: "entry",
            inputTypeString: true,
            placeholder: '变量名称',
            isBindValue: false
        })
        layout.main?.left.appendChild(leftGroup)

        const group = new InputLinkNodeGroup( this, this.graphView as GraphView , {
            name: 'methods'
        })
        group.addInputLinkNode("方法(method)", InputLinkNodeFlow, {
            name: '',
            desc: '方法(method)',
            model: "output",
            inputTypeString: true,
            placeholder: '方法名称',
            isBindValue: false,
            showInput: true
        })
        .addInputLinkNode("静态方法(method)", InputLinkNodeFlow, {
            name: '',
            desc: '静态方法(method)',
            model: "output",
            inputTypeString: true,
            placeholder: '方法名称',
            isBindValue: false,
            showInput: true
        })
        .layout?.alignItems('flex-end')
        layout.main?.right.appendChild(group)

        this.group = group
        this.leftGroup = leftGroup
    }

    import(obj:any){
        this.group?.import(obj.userData.methods)
        this.leftGroup?.import(obj.userData.attributes)
        super.import(obj)
    }
}

Class.parser = ({node,toNode, regExpHelper, to}:any)=>{
    
    const className = node.userData.enters.funName

    if(to.name === 'quote') {
        return className
    }

    const next = toNode(node.outputs.output[0], 'enter')

    if(!regExpHelper.isValidVariableName(className)){
        throw new ParserError(node.uuid ,`"${className}" 不符合类命名规范`)
    }
    
    const attributes = node.userData.attributes || []  as any [] // 获取自定义的属性信息
    const methods = node.userData.methods || [] // 获取自定义的方法信息
    
    // 属性在 entrys 里面 
    let attributeCode = '' 
    attributes.map((item:any)=>{
        const linkNodeInfo = node.enters[item.uuid] // 获取链接信息
        const attrName = item.data
        if(regExpHelper.isValidVariableName(attrName)){
            const value = toNode(linkNodeInfo[0], 'output', 'null') 
            attributeCode += `${item.key.substring(0, 4) == '静态属性' ? ' static ' : ''}${attrName}=${value};`
        }
        else{
            throw new ParserError(node.uuid , `"${attrName}" 不符合类属性命名规范,  或未进行属性命名`)
        }
    })

    // 方法在 outputs 里面 
    let methodCode = '' 
    methods.map((item:any)=>{
        const linkNodeInfo = node.outputs[item.uuid] // 获取链接信息
        const methodName = item.data

        if(regExpHelper.isValidVariableName(methodName)){
            const body = toNode(linkNodeInfo[0], 'output', null) 
            if(body){
                methodCode += ` ${item.key === '静态方法(method)' ? ' static ' : ''} ${methodName}${body}`
            }
            else throw new ParserError(node.uuid , `未定义类${className} 的 ${methodName} 方法的方法体`)
        }
        else{
            throw new ParserError(node.uuid , `"${methodName}" 不符合类${className}方法命名规范,  或未进行方法命名`)
        }
    })
    
    return `class ${className}{${attributeCode}${methodCode}}${next}`
}